package com.crazy.mybatis.gerenator.service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.dom4j.Document;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.crazy.mybatis.gerenator.service.common.MethodEnum;
import com.crazy.mybatis.gerenator.service.util.NameUtil;
import com.crazy.mybatis.gerenator.service.util.TypeUtil;

@Component
public class Context implements InitializingBean {
	
	@Autowired
	private DataSource dataSource; // 数据源
	
	private String targetDir; // 文件输出目录
	
	@Value("${generator.config.beanPackage}")
	private String beanPackage; // 实体类package
	
	@Value("${generator.config.mapperPackage}")
	private String mapperPackage; // mapper接口类package
	
	@Value("${generator.config.tableName}")
	private String tableName; // 指定的数据库表名
	
	private String primaryKey; // 主键字段
	
	@Value("${generator.config.beanName}")
	private String beanName; // 指定的实体类名称，缺省根据tableName生成
	
	@Value("${generator.config.methodSet}")
	private String methodSetStr; // 需要生成的方法
	
	private Set<MethodEnum> methodSet = new HashSet<MethodEnum>();
	
	private Document document; // 文档对象
	
	private List<String> columnList = new ArrayList<String>();
	
	private List<String> propertyList = new ArrayList<String>();
	
	private Map<String, String> columnPropertyMap = new HashMap<String, String>();
	
	private Map<String, String> columnJdbcTypeMap = new HashMap<String, String>();
	
	private Map<String, String> propertyTypeMap = new HashMap<String, String>();

	public Document getDocument() {
		return document;
	}

	public void setDocument(Document document) {
		this.document = document;
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public String getTargetDir() {
		return targetDir;
	}

	public void setTargetDir(String targetDir) {
		this.targetDir = targetDir;
	}

	public String getBeanPackage() {
		return beanPackage;
	}

	public void setBeanPackage(String beanPackage) {
		this.beanPackage = beanPackage;
	}

	public String getMapperPackage() {
		return mapperPackage;
	}

	public void setMapperPackage(String mapperPackage) {
		this.mapperPackage = mapperPackage;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getBeanName() {
		return beanName;
	}

	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}

	public Set<MethodEnum> getMethodSet() {
		return methodSet;
	}

	public void setMethodSet(Set<MethodEnum> methodSet) {
		this.methodSet = methodSet;
	}

	public List<String> getColumnList() {
		return columnList;
	}

	public List<String> getPropertyList() {
		return propertyList;
	}

	public Map<String, String> getColumnPropertyMap() {
		return columnPropertyMap;
	}

	public Map<String, String> getColumnJdbcTypeMap() {
		return columnJdbcTypeMap;
	}

	public String getPrimaryKey() {
		return primaryKey;
	}

	public Map<String, String> getPropertyTypeMap() {
		return propertyTypeMap;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// 获取元数据
		Connection connection = this.dataSource.getConnection();
		Statement statment = connection.createStatement();
		ResultSet rs = statment.executeQuery("select * from " + this.tableName + " limit 0");
		ResultSetMetaData meta = rs.getMetaData();
		for (int i = 0; i < meta.getColumnCount(); i++) {
			String column = meta.getColumnLabel(i+1);
			this.columnList.add(column);
			String property = NameUtil.toCamel(column);
			this.propertyList.add(property);
			this.columnPropertyMap.put(column, property);
			this.columnJdbcTypeMap.put(column, TypeUtil.getJdbcType(meta.getColumnType(i+1)));
			this.propertyTypeMap.put(property, TypeUtil.getPropertyType(meta.getColumnType(i+1)));
		}
		// 获取主键列名称
		ResultSet pkResultSet = connection.getMetaData().getPrimaryKeys(null, null, this.tableName);
		while (pkResultSet.next()) {
			this.primaryKey = pkResultSet.getString("COLUMN_NAME");
		}
		connection.close();
		
		String[] methodNames = methodSetStr.split(",");
		for (String mName : methodNames) {
			MethodEnum e = MethodEnum.findByValue(mName);
			if (e != MethodEnum.UNKNOWN) {
				this.methodSet.add(e);
			}
		}
	}
	
	public String getAbsoluteModel() {
		return this.beanPackage + "." + this.beanName;
	}
	
}
